<!DOCTYPE html>
<HTML>
<HEAD><meta name="viewport" content="width=device-width, initial-scale=1">
<Title>Surface Texture</Title>
<link type='text/css' rel='Stylesheet' href="maxchartapi.css" />
</HEAD>
<body bgcolor="#FFFFFF" text="#000000" topmargin="0" leftmargin="0" rightmargin="0" marginwidth="0" marginheight="0">

<p class="heading0">ChartDirector 7.0 (Java Edition)</p>
<p class="heading1">Surface Texture</p>
<hr class="separator">
<div class="content">
<img src="images/surfacetexture0.png" width='480' height='450'>&nbsp;&nbsp;<img src="images/surfacetexture1.png" width='480' height='450'>&nbsp;&nbsp;<img src="images/surfacetexture2.png" width='480' height='450'>
<br><br>
This example demonstrates adding images on surface charts using <a href="SurfaceChart.setSurfaceTexture.htm">SurfaceChart.setSurfaceTexture</a>.<br><br>
Surface image provides a very flexible way to mark or highlight the surface. The surface image can be a regular image or an image created by another chart. It can be semi-transparent so it would not block the underlying surface.
</div>
<p class="heading1a">Source Code Listing</p>
<div class="content">
<b>[JSP Version]</b> jspdemo/surfacetexture.jsp
<div class='codeblock'><code class='pre'>&lt;%@page import="ChartDirector.*, java.util.*" %&gt;
&lt;%!
// Use a bubble chart as the surface texture
private void addBubbleTexture(SurfaceChart sc)
{
    // Set the original surface color to be from grey (0xbbbbbb) to light grey (0xeeeeee) based on
    // the z-value. This will become the background color of the surface.
    sc.colorAxis().setColorGradient(true, new int[]{0xbbbbbb, 0xeeeeee});

    // The data values for the red bubbles
    double[] dataX0 = {-5, -2, 1, 7};
    double[] dataY0 = {2, 4, -2, -6};
    double[] dataZ0 = {20, 60, 50, 85};

    // The data values for the blue bubbles
    double[] dataX1 = {5, -5, -3};
    double[] dataY1 = {3, -4, 7};
    double[] dataZ1 = {100, 85, 95};

    // Create a bubble chart of the same size as the surface XY size
    XYChart c = new XYChart(sc.getPlotRegionWidth(), sc.getPlotRegionDepth(), Chart.Transparent);
    c.setPlotArea(0, 0, c.getWidth(), c.getHeight(), -1, -1, Chart.Transparent, Chart.Transparent);

    // Synchronize the bubble chart axis scale to the surface axis scale. As the surface axes are
    // visible, we can hide the bubble chart axes.
    c.yAxis().syncAxis(sc.yAxis());
    c.xAxis().syncAxis(sc.xAxis());
    c.xAxis().setColors(Chart.Transparent);
    c.yAxis().setColors(Chart.Transparent);

    // Add bubbles with the semi-transparent red color (0x7fff3333). Also add a matching legend
    // entry to the surface chart.
    c.addScatterLayer(dataX0, dataY0, "", Chart.CircleSymbol, 9, 0x7fff3333, 0x7fff3333
        ).setSymbolScale(dataZ0);
    sc.getLegend().addKey("Hot Zone", 0x7fff3333);

    // Add bubbles with the semi-transparent blue color (0x7f3333ff). Also add a matchine legend
    // entry to the surface chart
    c.addScatterLayer(dataX1, dataY1, "", Chart.CircleSymbol, 9, 0x7f3333ff, 0x7f3333ff
        ).setSymbolScale(dataZ1);
    sc.getLegend().addKey("Wet Zone", 0x7f3333ff);

    // Before we generate the bubble chart as texture, we must layout the surface chart first. It is
    // because the bubble chart axis scale depends on the surface chart axis scale.
    sc.layout();

    // Output the bubble chart and save it as a resource
    sc.setResource("texture", c.makeChart3());
    // Use the resource as the texture
    sc.setSurfaceTexture(sc.patternColor("@/texture"));
}

// Use a polar chart as the surface texture
private void addPolarTexture(SurfaceChart sc)
{
    sc.setSurfaceAxisGrid(Chart.Transparent, Chart.Transparent);

    PolarChart c = new PolarChart(sc.getPlotRegionWidth(), sc.getPlotRegionDepth(),
        Chart.Transparent);

    c.setPlotArea(c.getWidth() / 2, c.getHeight() / 2, c.getWidth() / 2);

    // Use alternative light grey/dark grey circular background color
    c.setPlotAreaBg(0xaf000000, Chart.Transparent);

    // Set the grid style to circular grid
    c.setGridStyle(false);

    // Set angular axis as 0 - 360, with a spoke every 30 units
    c.angularAxis().setLinearScale(0, 360, 30);
    c.angularAxis().setLabelStyle("normal", 8, Chart.Transparent);
    c.radialAxis().setLinearScale(0, 10, 2);
    c.radialAxis().setColors(Chart.Transparent, Chart.Transparent);

    // Output the polar chart and save it as a resource
    sc.setResource("texture", c.makeChart3());
    // Use the resource as the texture
    sc.setSurfaceTexture(sc.patternColor("@/texture"));
}


// Function to create the demo charts
void createChart(WebChartViewer viewer, int chartIndex)
{
    // The x and y coordinates of the grid
    double[] dataX = {-10, -9, -8, -7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
    double[] dataY = {-10, -9, -8, -7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10};

    // The values at the grid points. In this example, we will compute the values using the formula
    // z = x * y.
    double[] dataZ = new double[dataX.length * dataY.length];
    for(int yIndex = 0; yIndex &lt; dataY.length; ++yIndex) {
        for(int xIndex = 0; xIndex &lt; dataX.length; ++xIndex) {
            dataZ[yIndex * dataX.length + xIndex] = dataX[xIndex] * dataY[yIndex];
        }
    }

    // Create a SurfaceChart object of size 480 x 450 pixels
    SurfaceChart c = new SurfaceChart(480, 450);

    // Set the center of the plot region at (240, 210), and set width x depth x height to 240 x 240
    // x 200 pixels
    c.setPlotRegion(240, 210, 240, 240, 200);

    // Set the elevation and rotation angles to 30 and 15 degrees
    c.setViewAngle(30, 15);

    // Set the data to use to plot the chart
    c.setData(dataX, dataY, dataZ);

    // Spline interpolate data to a 80 x 80 grid for a smooth surface
    c.setInterpolation(80, 80);

    // Reserve 50 pixels at the bottom of the z-axis to allow for the XY projection
    c.zAxis().setMargin(0, 50);

    // Add XY projection
    c.addXYProjection();

    // Use semi-transparent black (0xc0000000) for x and y major surface grid lines. Use dotted
    // style for x and y minor surface grid lines.
    int majorGridColor = 0xc0000000;
    int minorGridColor = c.dashLineColor(majorGridColor, Chart.DotLine);
    c.setSurfaceAxisGrid(majorGridColor, majorGridColor, minorGridColor, minorGridColor);

    // Get the surface texture
    if (chartIndex == 0) {
        // Surface texture is a bubble chart
        c.addTitle("&lt;*underline=2*&gt;Bubble Chart Texture", "Arial Bold", 16);

        // This texture uses the legend box, so we need to add a legend box to the chart at (490,
        // 200).
        LegendBox b = c.addLegend(490, 200, true, "Arial Bold", 10);
        b.setBackground(Chart.Transparent, Chart.Transparent);
        b.setMaxWidth(c.getWidth() - 490 - 1);

        // Add the texture
        addBubbleTexture(c);
    } else if (chartIndex == 1) {
        // Surface Texture is a polar chart
        c.addTitle("&lt;*underline=2*&gt;Polar Chart Texture", "Arial Bold", 16);

        // This texture uses the color axis, so we add the color axis at (420, 75)
        ColorAxis cAxis = c.setColorAxis(420, 75, Chart.TopLeft, 200, Chart.Right);

        // By default, the color axis synchronizes with the z-axis. We cancel the synchronization so
        // that the color axis will auto-scale independently.
        cAxis.syncAxis(null);

        // Add the texture
        addPolarTexture(c);
    } else {
        // Surface Texture is an image
        c.addTitle("&lt;*underline=2*&gt;Image Texture", "Arial Bold", 16);

        // Use a DrawArea to load the image
        DrawArea d = new DrawArea();

        //Set search path to current JSP directory for loading icon images
        d.setSearchPath(getServletConfig().getServletContext(), viewer.getRequest());

        // Load image and resize it to fit the plot region
        d.load("maptexture.png");
        d.resize(c.getPlotRegionWidth(), c.getPlotRegionDepth());

        // Set the DrawArea as a resource
        c.setResource("texture", d);
        // Use the resource as the texture
        c.setSurfaceTexture(c.patternColor("@/texture"));
    }

    // Set contour lines to semi-transparent white (7fffffff)
    c.setContourColor(0x7fffffff);

    // Set the x, y and z axis titles using 10 pt Arial Bold font
    c.xAxis().setTitle("X Title&lt;*br*&gt;Placeholder", "Arial Bold", 10);
    c.yAxis().setTitle("Y Title&lt;*br*&gt;Placeholder", "Arial Bold", 10);
    c.zAxis().setTitle("Z Title Placeholder", "Arial Bold", 10);

    // Output the chart
    viewer.setChart(c, Chart.SVG);
}
%&gt;
&lt;%
// This example includes 3 charts
WebChartViewer[] viewers = new WebChartViewer[3];
for (int i = 0; i &lt; viewers.length; ++i) {
    viewers[i] = new WebChartViewer(request, "chart" + i);
    createChart(viewers[i], i);
}
%&gt;
&lt;!DOCTYPE html&gt;
&lt;html&gt;
&lt;head&gt;
    &lt;title&gt;Surface Texture&lt;/title&gt;
    &lt;!-- Include ChartDirector Javascript Library to support chart interactions --&gt;
    &lt;script type="text/javascript" src="cdjcv.js"&gt;&lt;/script&gt;
&lt;/head&gt;
&lt;body style="margin:5px 0px 0px 5px"&gt;
    &lt;div style="font:bold 18pt verdana;"&gt;
        Surface Texture
    &lt;/div&gt;
    &lt;hr style="border:solid 1px #000080; background:#000080" /&gt;
    &lt;div style="font:10pt verdana; margin-bottom:1.5em"&gt;
        &lt;a href="viewsource.jsp?file=&lt;%=request.getServletPath()%&gt;"&gt;View Source Code&lt;/a&gt;
    &lt;/div&gt;
    &lt;!-- ****** Here are the chart images ****** --&gt;
    &lt;%
        for (int i = 0; i &lt; viewers.length; ++i) {
            out.write(viewers[i].renderHTML(response));
            out.write(" ");
        }
    %&gt;
&lt;/body&gt;
&lt;/html&gt;</code></div>
</div>
<br><hr class="separator"><div class="copyright">&copy; 2022 Advanced Software Engineering Limited. All rights reserved.</div>
</body>
</HTML>
